package me.zhengjie.tool;


import me.zhengjie.vo.InterestVo;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: Chenwei
 * @Description:
 * @Date: Created in 2021-03-25
 * 计息工具类
 */
public class InterestUtil {

    private static final String PASSTHROUGH = "$$$$$$"; // 通配符

    /**
     * @param interestRates 利率参数
     * @param aaa030        利率类型
     * @param aab359
     * @param aae003        费款所属期
     * @param aae041        计息开始期号
     * @param aae042        计息结束期号
     * @param principal     本金
     * @return
     */
    public static InterestVo calInterest(List<Map> interestRates, String aaa030, String aab359, Integer aae003, Integer aae041, Integer aae042, BigDecimal principal) {
        if (ValidateUtil.isEmpty(interestRates)) {
            throw new IllegalArgumentException("利率参数不能为空！");
        }
        if (ValidateUtil.isEmpty(aaa030)) {
            throw new IllegalArgumentException("利率类型不能为空！");
        }
        if (ValidateUtil.isEmpty(aae041)) {
            throw new IllegalArgumentException("开始年月不能为空！");
        }
        if (ValidateUtil.isEmpty(aae042)) {
            throw new IllegalArgumentException("结束年月不能为空！");
        }
        if (ValidateUtil.isEmpty(principal)) {
            throw new IllegalArgumentException("计息本金不能为空！");
        }
        BigDecimal thatYearInterest = BigDecimal.ZERO; // 当前年度利息
        BigDecimal otherYearInterest = BigDecimal.ZERO; // 跨年利息

        if (principal.compareTo(BigDecimal.ZERO) == 0) {
            return new InterestVo();
        }
        // 过滤经办机构之外的利率参数
        if (ValidateUtil.isNotEmpty(aab359)) {
            interestRates = interestRates.stream().filter(x -> x.get("aab359").equals(aab359) || x.get("aab359").equals(PASSTHROUGH)).collect(Collectors.toList());
        }
        // 过滤掉利率类型外的利率参数
        interestRates = interestRates.stream().filter(x -> x.get("aaa030").equals(aaa030)).collect(Collectors.toList());

        if (ValidateUtil.isEmpty(interestRates)) {
            throw new IllegalArgumentException("没有获取到利率参数，请检查利率参数");
        }
        Integer beginMonth = aae041;
        while (beginMonth <= aae042 && !ValidateUtil.isEmpty(interestRates)) {
            // 获取月利率
            BigDecimal rate = getRateOfMonth(beginMonth, interestRates);

            if (isThatYear(aae003, beginMonth)) { // 计算当前年度利息
                thatYearInterest = thatYearInterest.add(principal.multiply(rate));
            } else { // 计算跨年利息
                otherYearInterest = otherYearInterest.add(principal.multiply(rate));
            }
            // 开始年月加1个月
            beginMonth = Ym.addMonths(beginMonth, 1);
        }
        return new InterestVo(thatYearInterest, otherYearInterest, thatYearInterest.add(otherYearInterest));
    }

    /**
     * 控制建账年月前不计息
     *
     * @param interestRates 利率参数
     * @param aaa030        利率类型
     * @param aab359
     * @param aae206        建账年月
     * @param aae003        费款所属期
     * @param aae041        计息开始期号
     * @param aae042        计息结束期号
     * @param principal     本金
     * @return
     */
    public static InterestVo calInterest(List<Map> interestRates, String aaa030, String aab359, Integer aae206, Integer aae003, Integer aae041, Integer aae042, BigDecimal principal) {
        if (ValidateUtil.isEmpty(interestRates)) {
            throw new IllegalArgumentException("利率参数不能为空！");
        }
        if (ValidateUtil.isEmpty(aaa030)) {
            throw new IllegalArgumentException("利率类型不能为空！");
        }
        if (ValidateUtil.isEmpty(aae041)) {
            throw new IllegalArgumentException("开始年月不能为空！");
        }
        if (ValidateUtil.isEmpty(aae042)) {
            throw new IllegalArgumentException("结束年月不能为空！");
        }
        if (ValidateUtil.isEmpty(principal)) {
            throw new IllegalArgumentException("计息本金不能为空！");
        }
        if (ValidateUtil.isEmpty(aae206)) {
            throw new IllegalArgumentException("建账年月不能为空！");
        }
        BigDecimal thatYearInterest = BigDecimal.ZERO; // 当前年度利息
        BigDecimal otherYearInterest = BigDecimal.ZERO; // 跨年利息

        if (principal.compareTo(BigDecimal.ZERO) == 0) {
            return new InterestVo();
        }
        // 过滤经办机构之外的利率参数
        if (ValidateUtil.isNotEmpty(aab359)) {
            interestRates = interestRates.stream().filter(x -> x.get("aab359").equals(aab359) || x.get("aab359").equals(PASSTHROUGH)).collect(Collectors.toList());
        }
        // 过滤掉利率类型外的利率参数
        interestRates = interestRates.stream().filter(x -> x.get("aaa030").equals(aaa030)).collect(Collectors.toList());

        if (ValidateUtil.isEmpty(interestRates)) {
            throw new IllegalArgumentException("没有获取到利率参数，请检查利率参数");
        }
        Integer beginMonth = aae041;
        while (beginMonth <= aae042 && !ValidateUtil.isEmpty(interestRates)) {
            // 获取月利率
            BigDecimal rate = getRateOfMonth(beginMonth, interestRates);

            //如果小于建账年月，不计息
            if (beginMonth < aae206) {
                rate = BigDecimal.ZERO;
            }

            if (isThatYear(aae003, beginMonth)) { // 计算当前年度利息
                thatYearInterest = thatYearInterest.add(principal.multiply(rate));
            } else { // 计算跨年利息
                otherYearInterest = otherYearInterest.add(principal.multiply(rate));
            }
            // 开始年月加1个月
            beginMonth = Ym.addMonths(beginMonth, 1);
        }
        return new InterestVo(thatYearInterest, otherYearInterest, thatYearInterest.add(otherYearInterest));
    }

    /**
     * 判断计息时间是否是当前年度
     *
     * @param aae003
     * @return
     */
    public static boolean isThatYear(Integer aae003, Integer aae003_interest) {
        NPETool.isEmptyThrowException(aae003, "费款所属期");
        NPETool.isEmptyThrowException(aae003_interest, "计息期");
        return aae003.toString().substring(0, 4).equals(aae003_interest.toString().substring(0, 4));
    }

    /**
     * 获取月利率
     *
     * @param issue
     * @param interestRates
     * @return
     */
    public static BigDecimal getRateOfMonth(Integer issue, List<Map> interestRates) {
        List<Map> matchedRates = interestRates.stream().filter(interestRate ->
                (Integer.valueOf(interestRate.get("aae041").toString()) <= issue && issue <= Integer.valueOf(interestRate.get("aae042").toString()))).collect(Collectors.toList());
        if (ValidateUtil.isEmpty(matchedRates)) {
            throw new IllegalArgumentException("未读取到" + issue + "期利率参数！");
        }
        if (matchedRates.size() > 1) {
            throw new IllegalArgumentException("读取到多条" + issue + "期利率参数！");
        }
        return ((BigDecimal) matchedRates.get(0).get("aaa031")).divide(BigDecimal.valueOf(12), 10, BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal getRateOfYear(Integer issue, List<Map> interestRates) {
        List<Map> matchedRates = interestRates.stream().filter(interestRate ->
                (Integer.valueOf(interestRate.get("aae041").toString()) <= issue && issue <= Integer.valueOf(interestRate.get("aae042").toString()))).collect(Collectors.toList());
        if (ValidateUtil.isEmpty(matchedRates)) {
            throw new IllegalArgumentException("未读取到" + issue + "期利率参数！");
        }
        if (matchedRates.size() > 1) {
            throw new IllegalArgumentException("读取到多条" + issue + "期利率参数！");
        }
        return ((BigDecimal) matchedRates.get(0).get("aaa031"));
    }

    public static BigDecimal getRateOfYear(Integer issue, String aaa030, List<Map> interestRates) {
        List<Map> matchedRates = interestRates.stream().filter(interestRate ->
                (Integer.valueOf(interestRate.get("aae041").toString()) <= issue && issue <= Integer.valueOf(interestRate.get("aae042").toString()))
                        && aaa030.equals(interestRate.get("aaa030").toString())).collect(Collectors.toList());
        if (ValidateUtil.isEmpty(matchedRates)) {
            throw new IllegalArgumentException("未读取到" + issue + "期利率参数！");
        }
        if (matchedRates.size() > 1) {
            throw new IllegalArgumentException("读取到多条" + issue + "期利率参数！");
        }
        return ((BigDecimal) matchedRates.get(0).get("aaa031"));
    }

    public static BigDecimal getRateOfYearNull(Integer issue, List<Map> interestRates) {
        List<Map> matchedRates = interestRates.stream().filter(interestRate ->
                (Integer.valueOf(interestRate.get("aae041").toString()) <= issue && issue <= Integer.valueOf(interestRate.get("aae042").toString()))).collect(Collectors.toList());
        if (ValidateUtil.isEmpty(matchedRates)) {
            return null;
        }
        if (matchedRates.size() > 1) {
            throw new IllegalArgumentException("读取到多条" + issue + "期利率参数！");
        }
        return ((BigDecimal) matchedRates.get(0).get("aaa031"));
    }

    public static BigDecimal getRateOfYearNull(Integer issue, String aaa030, List<Map> interestRates) {
        List<Map> matchedRates = interestRates.stream().filter(interestRate ->
                (Integer.valueOf(interestRate.get("aae041").toString()) <= issue && issue <= Integer.valueOf(interestRate.get("aae042").toString()))
                        && aaa030.equals(interestRate.get("aaa030").toString())).collect(Collectors.toList());
        if (ValidateUtil.isEmpty(matchedRates)) {
            return null;
        }
        if (matchedRates.size() > 1) {
            throw new IllegalArgumentException("读取到多条" + issue + "期利率参数！");
        }
        return ((BigDecimal) matchedRates.get(0).get("aaa031"));
    }
}
